package net.oschina.allchat.message.processing.json.parsers.error;

import java.util.List;

import net.oschina.allchat.message.processing.Attribute;
import net.oschina.allchat.message.processing.BadMessageException;
import net.oschina.allchat.message.processing.ElementParserAdaptor;
import net.oschina.allchat.message.processing.IElementParser;
import net.oschina.allchat.message.processing.IParser;
import net.oschina.allchat.message.processing.IParserFactory;
import net.oschina.allchat.message.processing.IParsingContext;
import net.oschina.allchat.message.processing.ParserAdaptor;
import net.oschina.allchat.message.processing.ParsingContext;
import net.oschina.allchat.message.processing.json.ParsingUtils;
import net.oschina.allchat.protocol.core.LangText;
import net.oschina.allchat.protocol.core.Protocol;

public abstract class ErrorDetailsParserFactory implements IParserFactory<Object> {
	private static final String PATH_ROOT = "/";

	@Override
	public IParser<Object> create() {
		return new ErrorDetailsParser();
	}
	
	public class ErrorDetailsParser extends ParserAdaptor<Object> {

		private static final String PROTOCOL_TEXT_LOCAL_NAME = "text";

		public ErrorDetailsParser() {
			super(null);
		}
		
		@Override
		public Object createObject() {
			return null;
		}
		
		@Override
		public IElementParser<Object> getElementParser(String parsingPath) {
			if (PATH_ROOT.equals(parsingPath)) {
				return new ElementParserAdaptor<Object>() {
					@Override
					public void processAttributes(IParsingContext<Object> context, List<Attribute<?>> attributes) {
						Protocol protocol = context.getProtocolChain().get(context.getProtocolChain().size() - 1);
						
						if (PROTOCOL_TEXT_LOCAL_NAME.equals(protocol.getLocalName())) {
							String lang = ParsingUtils.processLangTextAttributes(attributes);
							((ParsingContext<Object>)context).setObject(new LangText(null, lang));
						} else {
							((ParsingContext<Object>)context).setObject(protocol.getLocalName());
						}
					}
					
					@Override
					public void processText(IParsingContext<Object> context, String text) {
						Protocol protocol = context.getProtocolChain().get(context.getProtocolChain().size() - 1);
						
						if (PROTOCOL_TEXT_LOCAL_NAME.equals(protocol.getLocalName())) {
							((LangText)(context.getObject())).setText(text);
						} else {
							if (text != null) {
								throw new BadMessageException(String.format("text not allowed in here. protocol %s", context.getProtocolChain()));
							}
						}
					}
				};
			}

			return null;
		} 
		
	}
}
